package presentation.web;

import java.rmi.RemoteException ;

import java.util.Map ;
import java.util.Vector ;

import jaxcent.HtmlButton ;
import jaxcent.HtmlInputText ;
import jaxcent.HtmlPara ;
import jaxcent.HtmlTable ;
import presentation.UIDirectory ;
import presentation.UIThread ;
import util.Log ;
import util.NotFoundException ;
import util.Subsystem ;
import domain.user.Privilege ;
import domain.user.UnpermittedActionException ;

/**
 * The class for viewing a directory page
 *
 */
public class ViewDirectoryPage extends MainPage
{
	private HtmlTable directories ;
	private HtmlTable threads ;
	private HtmlPara directoryName ;
	private UIDirectory currentDirectory ;

	private HtmlButton addDir;
	private HtmlInputText dirNameField;
	private HtmlButton addTopic;

	/** place for error messages **/
	private HtmlPara errorsPara;
	private HtmlPara noDirectories;
	private HtmlPara noThreads;

	/**
	 * Instantiates a new view directory page.
	 */
	public ViewDirectoryPage()
	{
		super() ;
		this.currentDirectory = null ;
		try
		{
			Map<String, String> params = this.getPageParams() ;
			if (params.get("dir") == null)
			{
				this.currentDirectory = this.getForumLogic().getRootDirectory() ;
			}
			else
			{
				long dirId = Long.parseLong(params.get("dir")) ;
				this.currentDirectory = this.getForumLogic().getDirectory(dirId) ;
			}

			this.directoryName = new HtmlPara(this, "dirname") ;
			this.directoryName.setInnerHTML("Directory: " +this.currentDirectory.getName()) ;

		}
		catch (Exception e)
		{
			Log.getLogger(Subsystem.PAGE_RENDER).fine(e.getClass().getName() + "occured during creating root directory");
			this.navigateToErrorPage(e, null) ;
			return ;
		}

		try
		{
			this.noDirectories = new HtmlPara(this,"noDirs");
			this.noDirectories.setInnerHTML("");
			this.noThreads = new HtmlPara(this,"noThreads");
			this.noThreads.setInnerHTML("");
			this.loadDirectories(this.currentDirectory) ;
			this.loadThreads(this.currentDirectory) ;
			this.makeButtons();
			this.dirNameField = new HtmlInputText(this,"newDirName");
			this.showButtons();
			this.setErrors();
		}
		catch (Exception e)
		{
			this.navigateToErrorPage(e, null);
		}
	}

	/**
	 * Add Directory button handler
	 */
	private void addDirHandler()
	{
		try
		{
			String dirName = this.dirNameField.getValue();
			if(dirName!=null && (!(dirName.equals(""))))
			{
				long userId = this.getUser().getId();
				long containerDirectoryId = this.currentDirectory.getId();
				UIDirectory newAddedDir = this.getForumLogic().addDirectory(userId, containerDirectoryId, dirName);
				Log.getLogger(Subsystem.PAGE_RENDER).finest("user " + userId + " has add directory "+dirName+" with id "+newAddedDir.getId());
				loadDirectories(this.currentDirectory);
				this.dirNameField.setValue("");
				this.errorsPara.setInnerHTML("");
				this.noDirectories.setInnerHTML("");
			}
			else{
				this.errorsPara.setInnerHTML("please enter a name for the directory!");
				return;
			}

		}
		catch (NotFoundException e)
		{
			Log.getLogger(Subsystem.PAGE_RENDER).fine("the container directory has been deleted during adding a directory");
			this.navigateToErrorPage("The container directory has been deleted", null) ;
		}
		catch (Exception e)
		{
			Log.getLogger(Subsystem.PAGE_RENDER).fine(e.getClass().getName() + "occured during adding a directory");
			this.navigateToErrorPage(e, null) ;
		}
	}

	private void addThreadHandler()
	{
		try
		{
			this.navigateToPage("add thread", "dir=" + this.currentDirectory.getId()) ;
		}
		catch (Exception e)
		{
			Log.getLogger(Subsystem.PAGE_RENDER).fine("Exception occured while navigating to AddThread.html");
			this.navigateToErrorPage(e, this.threads) ;
		}
	}

	private void loadDirectories(final UIDirectory rootDirectory)
	{
		Vector<UIDirectory> children ;
		try
		{
			children = this.getForumLogic().getSubDirectories(rootDirectory.getId()) ;
		}
		catch (RemoteException e)
		{
			children = new Vector<UIDirectory>() ;
			Log.getLogger(Subsystem.PAGE_RENDER).fine(e.getClass().getName() + "occured during loading root subdirectories");
			this.navigateToErrorPage(e, null);
		}
		catch (NotFoundException e)
		{
			children = new Vector<UIDirectory>() ;
			Log.getLogger(Subsystem.PAGE_RENDER).fine(e.getClass().getName() + "occured during loading root subdirectories");
			this.navigateToErrorPage("Couldn't find root directory", null);
		}
		catch (Exception e)
		{
			children = new Vector<UIDirectory>() ;
			this.navigateToErrorPage(e, null);
		}

		try
		{
			this.directories = new HtmlTable(this, "directories") ;
			this.directories.deleteAllRows();
			String[] heading = { "<th style=\"color:black;font-size:23px\">Directories</th>" } ;
			this.directories.insertRow(-1, heading) ;
			this.directories.setBorder(1) ;
			this.directories.setWidth("700") ;

			if (children.isEmpty())
			{
				this.noDirectories.setInnerHTML("No directories were created yet");
				return;
			}
			for (UIDirectory dir: children)
			{
				this.directories.insertRow(-1, this.makeDirectoryRow(dir)) ;
			}
		}
		catch (Exception e)
		{
			Log.getLogger(Subsystem.PAGE_RENDER).fine(e.getClass().getName() + "occured during creating root subdirectories");
			this.navigateToErrorPage(e, null);
		}
	}

	private void loadThreads(final UIDirectory rootDirectory)
	{
		Vector<UIThread> topics ;
		try
		{
			topics = this.getForumLogic().getThreads(rootDirectory.getId()) ;
		}
		catch (RemoteException e)
		{
			topics = new Vector<UIThread>() ;
			Log.getLogger(Subsystem.PAGE_RENDER).fine(e.getClass().getName() + "occured during loading root subtopics");
			this.navigateToErrorPage(e, null);
		}
		catch (NotFoundException e)
		{
			topics = new Vector<UIThread>() ;
			Log.getLogger(Subsystem.PAGE_RENDER).fine(e.getClass().getName() + "occured during loading root subtopics");
			this.navigateToErrorPage("Couldn't find root directory", null);
		}
		catch (Exception e)
		{
			topics = new Vector<UIThread>() ;
			this.navigateToErrorPage(e, null);
		}

		try
		{
			this.threads = new HtmlTable(this, "threads") ;
			this.threads.deleteAllRows();
			String[] heading = { "<th style=\"color:black;font-size:23px\">Topics</th>" } ;
			this.threads.insertRow(-1, heading) ;
			this.threads.setBorder(1) ;
			this.threads.setWidth("700") ;

			if (topics.isEmpty())
			{
				this.noThreads.setInnerHTML("No topics were created yet");
				return;
			}
			for (UIThread thread: topics)
			{
				this.threads.insertRow(-1, this.makeThreadRow(thread)) ;
				this.makeDeleteButton(thread);
			}
		}
		catch (Exception e)
		{
			Log.getLogger(Subsystem.PAGE_RENDER).fine(e.getClass().getName() + "occured during creating root subtopics");
			this.navigateToErrorPage(e, null);
		}
	}

	private void makeButtons(){
		try
		{
			this.addDir = new HtmlButton(this,"addDirectory"){
		        @SuppressWarnings("synthetic-access")
				@Override
				protected void onClick() {
		        	ViewDirectoryPage.this.addDirHandler();
		        }
		    };
		    this.addTopic = new HtmlButton(this,"addThread"){
		        @SuppressWarnings("synthetic-access")
				@Override
				protected void onClick() {
		        	ViewDirectoryPage.this.addThreadHandler();
		        }
		    };
		}
		catch (Exception e)
		{
			this.navigateToErrorPage(e, null);
		}
	}

	private void makeDeleteButton(final UIThread thread)
	{
		try
		{
			if (this.getUser().isAllowed(Privilege.DELETE_THREAD))
			{
				@SuppressWarnings("unused")
				HtmlButton delete = new HtmlButton(this, "deleteThread" + thread.getId()) {
					 @SuppressWarnings("synthetic-access")
					@Override
					 protected void onClick()
					 {
						 	try
							{
								ViewDirectoryPage.this.getForumLogic().deleteThread(ViewDirectoryPage.this.getUser().getId(), ViewDirectoryPage.this.currentDirectory.getId(), thread.getId());
								Log.getLogger(Subsystem.PAGE_RENDER).finest("user " + ViewDirectoryPage.this.getUser().getId() + " has deleted the thread "+thread.getTopic());
								loadThreads(ViewDirectoryPage.this.currentDirectory);
							}
							catch (UnpermittedActionException e)
							{
								Log.getLogger(Subsystem.PAGE_RENDER).fine("user is not allowed to delete this thread");
								ViewDirectoryPage.this.navigateToErrorPage("You are not allowed to delete this thread", null);
							}
							catch (NotFoundException e)
							{
								Log.getLogger(Subsystem.PAGE_RENDER).fine("container directory of the deleted thread was deleted");
								ViewDirectoryPage.this.navigateToErrorPage("Container directory of the thread you deleted has been deleted", null);
							}
							catch (Exception e)
							{
								Log.getLogger(Subsystem.PAGE_RENDER).fine(e.getClass().getName() + " has occured during deleting a thread");
								ViewDirectoryPage.this.navigateToErrorPage(e, null);
							}
					 }
				} ;
			}
		}
		catch (Exception e)
		{
			Log.getLogger(Subsystem.PAGE_RENDER).fine("Exception has occured during creating delete thread element");
			ViewDirectoryPage.this.navigateToErrorPage(e, null);
		}
	}

	private String[] makeDirectoryRow(final UIDirectory dir)
	{
		String[] result = new String[1] ;
		try
		{
			String page = MainPage.pageLinks.get("view directory") ;
			result[0] = MainPage.makeLink(page, dir.getName(), "dir=" + dir.getId()) ;
		}
		catch (Exception e)
		{
			ViewDirectoryPage.this.navigateToErrorPage(e, null);
		}
		return result ;
	}

	private String[] makeThreadRow(final UIThread thread)
	{

		String[] result = new String[2] ;

		try
		{
			String page = MainPage.pageLinks.get("view thread") ;
			result[0] = MainPage.makeLink(page, thread.getTopic(), "thread=" + thread.getId()) ;
		}
		catch (Exception e)
		{
			this.navigateToErrorPage(e, null);
			return new String[0];
		}
		try
		{
			if(this.getUser().isAllowed(Privilege.DELETE_THREAD))
			{
				result[1] = "<button id=deleteThread" + thread.getId()+ " type=\"button\" >Delete</button>";
			}
		}
		catch (Exception e)
		{
			Log.getLogger(Subsystem.PAGE_RENDER).fine("Exception has occured during creating a thread row");
			this.navigateToErrorPage(e, null);
			return new String[0];
		}
		return result ;
	}

	private void setErrors()
	{
		try
		{
			this.errorsPara = new HtmlPara(this,"addDirErrorField");
			this.errorsPara.setInnerHTML("");
		}
		catch (Exception e)
		{
			Log.getLogger(Subsystem.PAGE_RENDER).fine("Exception has occured during creating an error paragraph");
			this.navigateToErrorPage(e, this.directories) ;
		}
	}

	private void showButtons()
	{
		try
		{
			this.dirNameField.hide();
			this.addDir.hide();
			this.addTopic.hide();

			if(this.getUser().isAllowed(Privilege.ADD_DIRECTORY))
			{
				this.addDir.show();
				this.dirNameField.show();
			}
			if(this.getUser().isAllowed(Privilege.ADD_THREAD))
			{
				this.addTopic.show();
			}
		}
		catch (Exception e)
		{
			Log.getLogger(Subsystem.PAGE_RENDER).fine("Jaxception has occured during showing add buttons");
			this.navigateToErrorPage(e, this.addDir) ;
		}
	}

}
